[小ネタ]RDSイベント イベントサブスクリプションとEventBridgeの違い
Amazon RDSイベントを検知する方法が、2種類あるので違いを調べてみました。結論としては、カテゴリレベルの通知か、イベントIDレベルの通知で異なります。
違いはどんなところ
そもそもイベントサブスクリプションの違いは何でしょう?起点がRDSイベントであることは一緒です。
RDSイベントサブスクリプション
RDSイベントサブスクリプションでは、RDSイベントをAmazon SNSをターゲットに通知します。
SNSが受け取ったRDSイベントは独自のイベントドキュメントにラップされます。
{
"Records": [
{
"EventVersion": "1.0",
"EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:rds-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
"EventSource": "aws:sns",
"Sns": {
"SignatureVersion": "1",
"Timestamp": "2019-01-02T12:45:07.000Z",
"Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==",
"SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem",
"MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
"Message": "{\"Event Source\":\"db-instance\",\"Event Time\":\"2019-01-02 12:45:06.000\",\"Identifier Link\":\"https://console.aws.amazon.com/rds/home?region=eu-west-1#dbinstance:id=dbinstanceid\",\"Source ID\":\"dbinstanceid\",\"Event ID\":\"http://docs.amazonwebservices.com/AmazonRDS/latest/UserGuide/USER_Events.html#RDS-EVENT-0002\",\"Event Message\":\"Finished DB Instance backup\"}",
"MessageAttributes": {},
"Type": "Notification",
"UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
"TopicArn":"arn:aws:sns:us-east-2:123456789012:sns-lambda",
"Subject": "RDS Notification Message"
}
}
]
}
Using AWS Lambda with Amazon RDS
Meesageに格納されたデータがRDSイベントデータです。見やすくすると以下のとおりです。
{
"Event Source": "db-instance",
"Event Time": "2019-01-02 12:45:06.000",
"Identifier Link": "https://console.aws.amazon.com/rds/home?region=eu-west-1#dbinstance:id=dbinstanceid",
"Source ID": "dbinstanceid",
"Event ID": "http://docs.amazonwebservices.com/AmazonRDS/latest/UserGuide/USER_Events.html#RDS-EVENT-0002",
"Event Message": "Finished DB Instance backup"
}
SNSからEメールで受け取るとrequestPayload
にラップされたjsonデータが格納されて通知されてます。
また、イベントサブスクリプションの通知設定では、ソースタイプでインタンスやクラスターなどの全てまたは特定のリソースのイベントカテゴリ単位で指定できます。
ソースタイプ
イベントカテゴリ
イベントカテゴリではイベントIDが存在します。例えばavailabilityカテゴリでは3つのイベントがあります。(RDSイベント一覧はこちら)
RDS-EVENT-0006 The DB instance restarted.
RDS-EVENT-0004 DB instance shutdown.
RDS-EVENT-0022 An error has occurred while restarting MySQL or MariaDB.
再起動のエラーが発生した場合だけ通知を受け取りたい場合は、RDSイベントサブスクリプションだとLambdaでイベントメッセージを処理してSNSで通知する構成が考えられます。
EventBridge
RDSイベントからEventBridgeにイベントが通知されます。
SNSを経由しない為、独自にラップされたjsonデータじゃなくて以下のようなjsonで渡されます。
{
"version": "0",
"id": "68f6e973-1a0c-d37b-f2f2-94a7f62ffd4e",
"detail-type": "RDS DB Instance Event",
"source": "aws.rds",
"account": "123456789012",
"time": "2018-09-27T22:36:43Z",
"region": "us-east-1",
"resources": [
"arn:aws:rds:us-east-1:123456789012:db:my-db-instance"
],
"detail": {
"EventCategories": [
"failover"
],
"SourceType": "DB_INSTANCE",
"SourceArn": "arn:aws:rds:us-east-1:123456789012:db:my-db-instance",
"Date": "2018-09-27T22:36:43.292Z",
"SourceIdentifier": "rds:my-db-instance",
"Message": "A Multi-AZ failover has completed."
}
}
EventBridgeではイベントパターンをカスタマイズできます。イベントカテゴリavailabilityの特定のメッセージ「An error has occurred while restarting MySQL or MariaDB.」に一致した場合はターゲット(SNSやLambdaなど)を実行することができます。
{
"source": ["aws.rds"],
"detail-type": ["RDS DB Instance Event"],
"detail": {
"EventCategories": ["availability"],
"Message": ["An error has occurred while restarting MySQL or MariaDB."]
}
}
どう使い分けるのか
イベントカテゴリ単位で通知を受けても良いならRDSサブスクリプションはアリだと思います。また、MessageにイベントIDが含まれるのはRDSサブスクリプションだけなので、LambdaなどでイベントIDで条件処理したい場合は有効です。EventBridgeでは、イベントパターンでフィルタリングできるのでLambda不要です。ただしEventBridgeのクォータで最大 2048 文字(変更不可)なので注意が必要です。
まとめ
使い分けとは脱線しますが、初めて採用するDBエンジンだったりDBエンジンのバージョンが異なる場合など挙動が把握できない場合などはイベントカテゴリ単位で通知を受け取ることが望ましいと考えます。安易にフィルタリングして必要なイベントを検知されなかったは避けるべきです。イベント通知を受け取った後の結果としてフィルタリングしていくかどうかを検討していきましょう。